package com.tuanzi.loan.web.bean.family;

import com.google.common.collect.Lists;
import com.tuanzi.loan.business.constants.sms.SmsCalculateMode;
import com.tuanzi.loan.business.constants.sms.SmsUserType;
import com.tuanzi.loan.business.entity.family.ProductInfo;
import com.tuanzi.loan.business.entity.family.RegisterRecommendActivity;
import com.tuanzi.loan.business.entity.sms.SmsSearchCondition;
import com.tuanzi.loan.business.entity.sms.SmsUserDefinition;
import com.tuanzi.loan.business.entity.statistics.ActivityChannelConfig;
import com.tuanzi.loan.business.entity.system.Dictionary;
import com.tuanzi.loan.business.service.family.ProductInfoService;
import com.tuanzi.loan.business.service.family.RegisterRecommendActivityService;
import com.tuanzi.loan.business.service.sms.*;
import com.tuanzi.loan.core.aspect.Debug;
import com.tuanzi.loan.core.exception.ValidateException;
import com.tuanzi.loan.core.util.GsonUtils;
import com.tuanzi.loan.vo.request.family.SmsCondition;
import com.tuanzi.loan.vo.request.family.SmsUserDefinitionRequest;
import com.tuanzi.loan.web.configuration.JSFInfoBean;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.joda.time.Days;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.faces.bean.ViewScoped;
import java.util.*;

import static com.tuanzi.loan.business.constants.DictionaryCode.*;

@Data
@Slf4j
@Debug
@Component
@ViewScoped
@EqualsAndHashCode(callSuper = true)
public class CalculateSmsBean extends JSFInfoBean<SmsCondition> {

	@Autowired
	private SmsSearchConditionService smsSearchConditionService;
	@Autowired
	private RegisterRecommendActivityService registerRecommendActivityService;
	@Autowired
	private SmsCalculateTaskService smsCalculateTaskService;
	@Autowired
	private ProductInfoService productInfoService;
	@Autowired
	private SmsUserDefinitionService smsUserDefinitionService;
	@Autowired
	private PhoneLocationService phoneLocationService;
	@Autowired
	private SmsSendTaskService smsSendTaskService;

	private List<SmsUserDefinition> smsUserDefinitions;
	private List<ProductInfo> productInfos;
	private List<RegisterRecommendActivity> activityTypes;
	private List<ActivityChannelConfig> activityChannelConfigs;
	private List<SmsSearchCondition> smsSearchConditions;
	private Integer selectedTemplateGroup;
	private String smsSearchConditionName;
	private Long selectedSearchConditionId;
	private List<Dictionary> smsTemplates;
	private Long estimatedSmsCount;
	private Map<String, String> provinces;
	private Map<String, String> firstPartyNames;

	@PostConstruct
	private void init() {
		activityTypes = registerRecommendActivityService.findAll();
		productInfos = productInfoService.findAll();
		smsSearchConditions = smsSearchConditionService.findAll();
		smsUserDefinitions = smsUserDefinitionService.findAll();
		provinces = phoneLocationService.findDistinctProvince();
		firstPartyNames = smsSendTaskService.findDistinctFirstNames();
		$ = new SmsCondition();
		$.setProvinces(Lists.newArrayList(provinces.keySet()));

		SmsUserDefinition blacklistDefinition = null;
		for (SmsUserDefinition definition : smsUserDefinitions) {
			if ("运营黑名单".equals(definition.getName())) {
				blacklistDefinition = definition;
				break;
			}
		}
		if (blacklistDefinition != null) {
			$.setSelectedUserDefinitionId(blacklistDefinition.getId());
			$.setUserDefinitionRequest(GsonUtils.toObject(blacklistDefinition.getContent(), SmsUserDefinitionRequest.class));
		}
		List<String> sexs = new ArrayList<>();
		sexs.add("1");
		sexs.add("0");
		$.setSexs(sexs);
	}

	@Override
	protected List<String> getDictionaryCodes() {
		return Lists.newArrayList(SMS_HIGH_QUALITY_USER_TYPE, SMS_ELIMINATE_BLACK_LIST, SMS_ELIMINATE_ACTION, SMS_ELIMINATE_ACTIVITY, SMS_USER_TYPE, PLATFORM, SMS_TEMPLATE_GROUP,
				SMS_TEMPLATE_BLACK_LIST, SMS_TEMPLATE_MARKETING, SMS_TEMPLATE_PULL_BACK, SMS_PLATFORM_CHANNEL, SMS_EXCLUDE_SENDED_DAY, SMS_ELIMINATE_CHECK_FIRST_PARTY);
	}

	public void onSelectUserDefinition() {
		if ($.getSelectedUserDefinitionId() == null) {
			$.setSelectedUserDefinitionId(null);
			$.setUserDefinitionRequest(null);
			return;
		}

		SmsUserDefinition userDefinition = smsUserDefinitions.stream().filter(x -> x.getId().equals($.getSelectedUserDefinitionId())).findFirst().get();
		$.setUserDefinitionRequest(GsonUtils.toObject(userDefinition.getContent(), SmsUserDefinitionRequest.class));
	}

	/**
	 * 预估用户数量
	 */
	public void onEstimate() {

		if(CollectionUtils.isEmpty($.getUserTypes())) {
			throw new ValidateException("请选择用户类型");
		}
		
		if($.getUserTypes().contains(SmsUserType.REGISTERED_USER) && $.getUserTypes().contains(SmsUserType.CHECKIN_BUT_NOT_REGISTER_USER)
				&& ($.getRecordStartTime() == null || $.getRecordEndTime() == null || $.getRegisterStartTime() == null || $.getRegisterEndTime() == null)) {
			throw new ValidateException("登记时间 & 注册时间必须输入");
		}
		
		if($.getUserTypes().contains(SmsUserType.CHECKIN_BUT_NOT_REGISTER_USER) && ($.getRecordStartTime() == null || $.getRecordEndTime() == null)) {
			throw new ValidateException("登记时间必须输入");
		}

		if($.getUserTypes().contains(SmsUserType.REGISTERED_USER) && ($.getRegisterStartTime() == null || $.getRegisterEndTime() == null)) {
			throw new ValidateException("注册时间必须输入");
		}
		

		if (Days.daysBetween(new DateTime($.getRecordStartTime()), new DateTime($.getRecordEndTime())).getDays() >= 31
				|| Days.daysBetween(new DateTime($.getRegisterStartTime()), new DateTime($.getRegisterEndTime())).getDays() >= 31) {
			throw new ValidateException("登记时间 & 注册时间间隔必须在1个月内");
		}
		
		if(CollectionUtils.isEmpty($.getProvinces())) {
			throw new ValidateException("请选择地区");
		}
		
		if($.getCalculateMode() == SmsCalculateMode.ONCE_TIMING_CALCULATE.ordinal()) {
			if(Objects.isNull($.getCalculateTime()) ) {
				throw new ValidateException("请输入定时计算时间");
			}
			
			if($.getCalculateTime().before(new Date())) {
				throw new ValidateException("定时计算时间必须大于当前时间");
			}
					
		}
		

		estimatedSmsCount = smsCalculateTaskService.estimateSmsCount($);
	}

	public String onGoToTaskHistory() {
		return redirect("/views/family/user-info/send-sms/sms-send-task.xhtml");
	}

	public String onGoToVoiceTaskHistory(){
		return redirect("/views/family/user-info/send-sms/sms-voice-send-task.xhtml");
	}

	public String onGoToCalculateHistory() {
		return redirect("/views/family/user-info/send-sms/sms-calculate-task.xhtml");
	}

	public String onGoToUserDefinition() {
		return redirect("/views/family/user-info/send-sms/sms-user-definition.xhtml");
	}

	public String onGoToCalculateExternalSms(){
		return redirect("/views/family/user-info/send-sms/calculate-external-sms.xhtml");
	}

	/**
	 * 计算用户数量
	 */
	public void onCalculateCount() {

		if(StringUtils.isEmpty($.getName())){
			throw new ValidateException("请输入任务名称");
		}

		if(CollectionUtils.isEmpty($.getTelecomOperators())){
			throw new ValidateException("请选择运营商");
		}
		
		if(CollectionUtils.isEmpty($.getUserTypes())) {
			throw new ValidateException("请选择用户类型");
		}
		

		if($.getUserTypes().contains(SmsUserType.REGISTERED_USER) && $.getUserTypes().contains(SmsUserType.CHECKIN_BUT_NOT_REGISTER_USER)
				&& ($.getRecordStartTime() == null || $.getRecordEndTime() == null || $.getRegisterStartTime() == null || $.getRegisterEndTime() == null)) {
			throw new ValidateException("登记时间 & 注册时间必须输入");
		}
		
		if($.getUserTypes().contains(SmsUserType.CHECKIN_BUT_NOT_REGISTER_USER)) {
			if(($.getRecordStartTime() == null || $.getRecordEndTime() == null)){
				throw new ValidateException("登记时间必须输入");
			}
			if(Days.daysBetween(new DateTime($.getRecordStartTime()), new DateTime(new Date())).getDays() == 0
					|| Days.daysBetween(new DateTime(new Date()), new DateTime($.getRecordEndTime())).getDays() == 0){
				if($.getCalculateMode() != SmsCalculateMode.ONCE_TIMING_CALCULATE.ordinal()){
					throw new ValidateException("计算当天登记用户请选择1次定时计算模式");
				}
			}
		}

		if($.getUserTypes().contains(SmsUserType.REGISTERED_USER)) {
			if(($.getRegisterStartTime() == null || $.getRegisterEndTime() == null)){
				throw new ValidateException("注册时间必须输入");
			}
			if(Days.daysBetween(new DateTime($.getRegisterStartTime()), new DateTime(new Date())).getDays() == 0
					|| Days.daysBetween(new DateTime(new Date()), new DateTime($.getRegisterEndTime())).getDays() == 0){
				if($.getCalculateMode() != SmsCalculateMode.ONCE_TIMING_CALCULATE.ordinal()){
					throw new ValidateException("计算当天注册用户请选择1次定时计算模式");
				}
			}
		}
		

		if (Days.daysBetween(new DateTime($.getRecordStartTime()), new DateTime($.getRecordEndTime())).getDays() >= 31
				|| Days.daysBetween(new DateTime($.getRegisterStartTime()), new DateTime($.getRegisterEndTime())).getDays() >= 31) {
			throw new ValidateException("登记时间 & 注册时间间隔必须在1个月内");
		}
		
		
		if(CollectionUtils.isEmpty($.getProvinces())) {
			throw new ValidateException("请选择地区");
		}

		if($.getCalculateMode() == SmsCalculateMode.ONCE_TIMING_CALCULATE.ordinal()) {
			if(Objects.isNull($.getCalculateTime()) ) {
				throw new ValidateException("请输入定时计算时间");
			}
			
			if($.getCalculateTime().before(new Date())) {
				throw new ValidateException("定时计算时间必须大于当前时间");
			}
					
		}
		
		if($.getSexs() == null || $.getSexs().size() <= 0){
			throw new ValidateException("请输入性别");
		}
		smsCalculateTaskService.addCalculateTask($);
		$ = new SmsCondition();
		addInfoMessage("操作成功,任务已加入计算队列");
	}

	public void onReset() {
		$ = new SmsCondition();
	}

	public void onSaveSearchCondition() {
		if (StringUtils.isBlank(smsSearchConditionName)) {
			addErrorMessage("请输入模板名称");
			return;
		}
		SmsSearchCondition smsSearchCondition = new SmsSearchCondition();
		smsSearchCondition.setId(selectedSearchConditionId);
		smsSearchCondition.setConditionContent(GsonUtils.toJson($));
		smsSearchCondition.setConditionName(smsSearchConditionName);
		smsSearchConditionService.save(smsSearchCondition);
		smsSearchConditions = smsSearchConditionService.findAll();
		addSuccessfullyMessage();
	}

	public void onSelectSearchCondition() {
		if (selectedSearchConditionId == null) {
			$ = new SmsCondition();
			smsSearchConditionName = null;
		} else {
			SmsSearchCondition smsSearchCondition = smsSearchConditions.stream().filter(x -> x.getId().equals(selectedSearchConditionId)).findFirst().get();
			$ = GsonUtils.toObject(smsSearchCondition.getConditionContent(), SmsCondition.class);
			smsSearchConditionName = smsSearchCondition.getConditionName();
		}
	}
}
